/**
 * chat.js              nodejs + extjs + socket.io.js聊天室js
 *
 * @author              mashanling(msl-138@163.com)
 * @date                2013-01-07 11:11:02
 * @last modify         2013-01-09 15:07:10 by mashanling
 */

var socket, viewport, win, treepanel, main,
icons = {
    boy: '/images/user_boy.png',
    girl: '/images/user_girl.png',
};

Ext.onReady(function () {
    if (username) {
        createSocket();
    }
    else {
        loginWin();
    }
});

function loginWin() {
    win = win || Ext.create('Ext.window.Window', {
        title: '登陆',
        border: false,
        modal: true,
        constrain: true,
        closable: false,
        layout: 'fit',
        width: 350,
        height: 200,
        items: {
            xtype: 'form',
            url: wwwroot + 'login',
            bodyPadding: 5,
            items: [{
                labelWidth: 50,
                name: 'username',
                xtype: 'textfield',
                fieldLabel: '用户名',
                allowBlank: false,
                blankText: '请输入用户名',
                labelAlign: 'right'
            }, {
                labelWidth: 50,
                xtype: 'combo',
                name: 'sex',
                value: 'boy',
                store: [
                    ['boy', '男'],
                    ['girl', '女']
                ],
                fieldLabel: '性别',
                allowBlank: false,
                blankText: '请选择性别',
                labelAlign: 'right'
            }, {
                xtype: 'button',
                type: 'submit',
                formBind: true,
                text: '登陆',
                handler: function() {
                    var form = this.up('form').getForm();
                    form.submit({
                        waitMsg: null,
                        success: function () {
                            createSocket();
                            username = htmlspecialchars(form.findField('username').getValue());
                            sex = form.findField('sex').getValue();
                            win.hide();
                        }
                    });
                }
            }]
        }
    }).show();
}

function createSocket() {
    createViewport();
    treepanel = Ext.getCmp('cmptree');
    main = Ext.getCmp('cmpmain');
    updateMain('<em style="color: gray">正在连接服务器，请稍后...</em>');
    socket = io.connect(wwwroot);
    socket.on('connect', function () {
        updateMain('<em style="color: gray">已经连接服务器</em>');
        login(username);
        this.emit('afterconnected', username, sex);
    }).on('user connected', function(username, sex) {
        login(username);
    }).on('afterdisconnect', function(username) {
        logout(username);
    }).on('user list', refreshOnline).on('public message', function(data) {
        updateMain('<b>' + data.username + '</b> ' + date(date.date) + '<br /><em style="color: gray">' + htmlspecialchars(data.msg) + '</em>');
    });
}

function createViewport() {
        viewport = Ext.create('Ext.container.Viewport', {
        layout: 'border',
        style: 'background: #fff',
        items: [/*{
            region: 'north',
            height: 65,
            bodyStyle: 'border: none; color: #fff; padding: 10px; background: #074E7C',
            html: 'nodejs + extjs + socket.io.js聊天室'
        }, */{
            region: 'west',
            xtype: 'treepanel',
            id: 'cmptree',
            width: 200,
            title: '当前在线',
            collapsible: true,
            split: true,
            minWidth: 200,
            rootVisible: false,
            lines: false,
            collapseMode: 'mini'
            /*store: Ext.create('Ext.data.TreeStore', {
                root: {
                    expanded: true
                }
            })*/
        }, {
            region: 'center',
            xtype: 'panel',
            layout: {
                type: 'vbox',
                align: 'stretch'
            },
            //style: 'margin-top: 4px;',
            defaults: {
                bodyStyle: 'padding: 4px; border: none',
            },
            items: [{
                id: 'cmpmain',
                tpl: '<p style="padding: 8px 0 2px 0; border-bottom: 1px dotted #ccc;">{data}</p>',
                tplWriteMode: 'append',
                flex: 1,
                autoScroll: true
            }, {
                style: 'border-top: 1px solid #ccc',
                xtype: 'form',
                height: 200,
                listeners: {
                    render: function() {
                        var me = this,
                        el = this.el,
                        btn = this.down('component[name=submit]');

                        Ext.each(['textarea'], function(item) {
                            el.on({
                                keydown: function(e) {
                                    e.ctrlKey && e.getKey() == e.ENTER && btn && !btn.isDisabled() && btn.fireHandler();
                                },
                                delegate: item
                            });
                        });
                    }
                },
                items: [{
                    width: 800,
                    height: 150,
                    xtype: 'textarea',
                    allowBlank: false,
                    blankText: '请输入内容'
                }, {
                    xtype: 'button',
                    name: 'submit',
                    formBind: true,
                    text: '提交',
                    handler: function() {
                        var el = this.previousSibling(), msg = Ext.String.trim(el.getValue());

                        if (msg) {
                            el.reset();

                            socket.emit('message', {
                                msg: msg,
                                date: new Date(),
                                username: username
                            });
                        }
                    }
                }]
            }]
        }]
    });
}

function login(username) {
    updateMain('<b>' + username + '</b> <em style="color: gray">进入聊天室</em>');
}

function logout(username) {

    if (username) {
        username = username.split('<>')[0];
        updateMain('<b>' + username + '</b> <em style="color: gray;">离开聊天室</em>');
        var node = treepanel.getRootNode().findChild('text', username);
        node && node.remove(true);
    }
}

function refreshOnline(users) {
    var children = [{
        text: username,
        icon: icons[sex],
        leaf: true
    }];

    Ext.Object.each(users, function(key, user) {
        user = user.split('<>');
        username != user[0] && children.push({ text: user[0], icon: icons[user[1]], leaf: true });
    });

    treepanel.setRootNode({
        text: 'root',
        expanded: true,
        children: children
    });
}

function str_pad(str, length, pad, padType) {
    str = String(str);
    length = length ? length : 10;
    pad = pad == undefined ? ' ' : pad;

    while (str.length < length) {
        str = padType == 'right' ? str + pad : pad + str;
    }

    return str;
}

function date(format, constructor) {

    if (typeof(constructor) == 'object') {//已经是日期类型
        var datetime = constructor;
    }
    else {
        var datetime = constructor ? new Date(constructor) : new Date();
    }

    format = format || 'Y-m-d H:i:s';

    var o = {
        'Y': datetime.getFullYear(),
        'm': datetime.getMonth() + 1,
        'd': datetime.getDate(),
        'H': datetime.getHours(),
        'i': datetime.getMinutes(),
        's': datetime.getSeconds()
    };

    for (var i in o) {
        _s = i == 'Y' ? o[i] : str_pad(o[i], 2, '0');//不为年，补0
        format = format.replace(new RegExp(i, 'g'), _s);
    }

    return format;
}

function htmlspecialchars(str) {
    return str.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;').replace(/\'/g, '&#39;');
}

function updateMain(content){
        main.update({
            data: content
        });
        main.body.scroll('b', 100000, true);
    }